package com.cby.android.olive.encrypt

import com.cby.android.olive.encrypt.Base64Utils.decodeToByte
import com.cby.android.olive.encrypt.Base64Utils.encode
import javax.crypto.Cipher
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.SecretKeySpec

/**
 * Description:Base64Utils-- Base64的加解密
 * <p>
 *     aes加密方式，保证与php服务端相同规则
 *    参考https://blog.csdn.net/flydream3618/article/details/86759420
 * </p>
 * @author 陈宝阳
 * @create 2020/8/3 16: 53
 */
object AESUtils {
    /**
     * IV长度应该为16，请跟服务端保持一致
     */
    private const val iv = "1234567812345678"

    /**
     * AES/CBC/PKCS5Padding默认对应PHP则为：AES-128-CBC
     */
    private const val CBC_PKCS5_PADDING = "AES/CBC/PKCS5Padding"

    /**
     * //AES 加密
     */
    private const val AES = "AES"

    /**
     *
     * @param key 密钥，这个key长度应该为16位，另外不要用KeyGenerator进行强化，否则无法跨平台
     * @param cleartext 需要加密的明文
     * @return
     */
    @JvmStatic
    fun encrypt(key: String, cleartext: String): String? {
        return try {
            val cipher = Cipher.getInstance(CBC_PKCS5_PADDING)
            val keyspec = SecretKeySpec(key.toByteArray(), AES)
            val ivspec = IvParameterSpec(iv.toByteArray())
            cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec)
            val encrypted = cipher.doFinal(cleartext.toByteArray())

            //base64编码一下
            encode(String(encrypted))
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }

    /**
     *
     * @param key 密钥，这个key长度应该为16位，另外不要用KeyGenerator进行强化，否则无法跨平台
     * @param encrypted
     * @return
     */
    @JvmStatic
    fun decrypt(key: String, encrypted: String?): String? {
        return try {
            val encrypted1 = decodeToByte(encrypted)
            val cipher = Cipher.getInstance(CBC_PKCS5_PADDING)
            val keyspec = SecretKeySpec(key.toByteArray(), AES)
            val ivspec = IvParameterSpec(iv.toByteArray())
            cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec)
            val original = cipher.doFinal(encrypted1)

            //转换为字符串
            String(original)
        } catch (e: Exception) {
            e.printStackTrace()
            null
        }
    }
}